package com.downguys.tool.elasticsearch;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkIndexByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryAction;
import org.elasticsearch.index.reindex.DeleteByQueryRequestBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Map;

/**
 * @author mingmin.zhou(弄死熊猫)
 * @mail 714387891@qq.com
 * @date 2017/4/12
 */
public class EsClient {

    public static final Logger LOGGER = LoggerFactory.getLogger(EsClient.class);

    private static TransportClient client;


    public static void init() throws UnknownHostException {
        Settings settings = Settings.builder()
                .put("cluster.name", "zmm-application")
                .put("client.transport.sniff", true).build();

        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(null), 9300));
    }

    public void destroy() throws UnknownHostException {
        client.close();
    }

    public static IndexResponse indexBytes(String index,String type,byte[] bytes){
        IndexResponse response = client.prepareIndex(index,type).setSource(bytes).get();
        return response;
    }

    public static IndexResponse indexString(String index,String type,String source){
        IndexResponse response = client.prepareIndex(index,type).setSource(source).get();
        return response;
    }

    public static GetResponse get(String index,String type,String id){
        System.out.println("index = [" + index + "], type = [" + type + "], id = [" + id + "]");
        GetResponse response = client.prepareGet(index,type,id).get();
        return response;
    }

    public static MultiSearchResponse getAll(){
        SearchRequestBuilder builder = client.prepareSearch().setQuery(QueryBuilders.queryStringQuery("mingmin.zhou"));
        MultiSearchResponse multiGetResponse = client.prepareMultiSearch().add(builder).get();
        return multiGetResponse;
    }

    public static DeleteResponse delete(String index,String type,String id){
        DeleteResponse deleteResponse = client.prepareDelete(index,type,id).get();
        return deleteResponse;
    }

    public static long synDeletedByQuery(String index, Map<String,Object> params){
        BulkIndexByScrollResponse response;

        DeleteByQueryRequestBuilder builder =
                DeleteByQueryAction.INSTANCE.newRequestBuilder(client);

        for(Map.Entry entry : params.entrySet()){
            builder.filter(QueryBuilders.matchQuery((String) entry.getKey(),entry.getValue()));
        }
        response = builder.source(index).get();

        // number of deleted documents
        long deleted = response.getDeleted();
        return deleted;
    }

    public static void asynDeletedByQuery(String index, Map<String,Object> params){
        DeleteByQueryRequestBuilder builder =
                DeleteByQueryAction.INSTANCE.newRequestBuilder(client);
        for(Map.Entry entry : params.entrySet()){
            builder.filter(QueryBuilders.matchQuery((String) entry.getKey(),entry.getValue()));
        }
        builder.source(index).execute(new ActionListener<BulkIndexByScrollResponse>() {
            @Override
            public void onResponse(BulkIndexByScrollResponse response) {
                long deleted = response.getDeleted();
            }
            @Override
            public void onFailure(Exception e) {
                LOGGER.error("asynDeletedByQuery error:",e);
            }
        });
    }



    public TransportClient getClient(){
        return client;
    }

    public static void main(String[] args) {

        try {
            init();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        JSONObject json = new JSONObject();

        json.put("china name","周铭敏");
        json.put("english name","mingmin.zhou");
        json.put("age",18);
        json.put("high",180);
        json.put("weight",68);
        json.put("emotion","single");
        json.put("create_time",new Date());




//        byte[] jsonStr = JSONObject.toJSONBytes(json);

        IndexResponse response = indexString("testindex","testtype",json.toJSONString());

        GetResponse response1 = get(response.getIndex(),response.getType(),response.getId());


        System.out.println("jsonStr = " + response1.getSource());
        System.out.println("jsonStrJson = " + JSONObject.parse(JSON.toJSONString(response1.getSource())));


        MultiSearchResponse multiGetResponse = getAll();

        long nbHits = 0;
        for (MultiSearchResponse.Item item : multiGetResponse.getResponses()) {
            SearchResponse r = item.getResponse();
            nbHits += r.getHits().getTotalHits();
            System.out.println("r.getHits().getHits() = " + r.getHits().getHits());
            for(SearchHit hit : r.getHits().getHits()){
                System.out.println("hit = " + JSON.toJSONString(hit));
            }
        }

        System.out.println("nbHits = " + nbHits);

        System.out.println("multiGetResponse = " + multiGetResponse.getResponses());


    }


}
